#include <iostream>
#include <vector>
#include <list>
#include <forward_list>
#include <deque>
#include <array>
#include <string>
#include <stack>
#include <queue>

using namespace std;

int main()
{
    list<string> authors = {"Milton", "Shakespeare", "Austen"};
    vector<const char*> articles = {"a", "an", "the"};

    list<string> list2(authors);
//    deque<string> authList(authors);  // 错误，容器类型不匹配
//    vector<string> words(articles);  // 错误，容器类型不匹配
    // 正确，迭代器方式的初始化，const char* 可以转换为 string
    forward_list<string> word(articles.begin(), articles.end());

    array<int, 42> arrar1;
    array<string, 1> array2 = {"string"};
    array<int, 10>::size_type i;
    int digs[10] = {0,1,2,3,4,5,6,7,8,9};
//    int cpy[10] = digs;  // 错误
    array<int, 10> digits = {0,1,2,3,4,5,6,7,9};
    array<int, 10> copy = digits;

    if (!array2.empty()) {
        auto val1 = *array2.begin();  // val1 是 array2 第一个元素值的拷贝
        auto val2 = array2.front();  // val2 是 array2 第一个元素值的拷贝
        auto last = array2.end();   // last 是 array2 的尾后迭代器
        auto val3 = *(--last);  // val3 是 array2 最后一个元素值的拷贝
        auto val4 = array2.back();  // val4 是 array2 最后一个元素值的拷贝
        cout << val1 << " " << val2 << " " << val3 << " " << val4 << endl;
    }
    // 删除元素
    list<int> lst = {0,1,2,3,4,5,6,7,8,9};
    auto it = lst.begin();
    while (it != lst.end()) {
        if (*it % 2) {
            it = lst.erase(it);
        } else {
            ++it;
        }
    }
    // 从 forward_list 中删除元素
    forward_list<int> flst = {0,1,2,3,4,5,6,7,8,9};
    auto prev = flst.before_begin();  // 指向 forward_list 的首前元素
    auto curr = flst.begin();  // 指向 forward_list 的第一个元素
    while (curr != flst.end()) {  // 仍有元素需要处理
        if (*curr % 2) {  // 奇数删除
            curr = flst.erase_after(prev);  // 注意删除是前面元素后面的元素，返回被删除元素之后的迭代器
        } else {
            prev = curr;  // 移动迭代器 curr，并指向下一个元素
            ++curr;  // curr 之前的元素
        }
    }

    // 傻瓜循环，删除偶数元素，复制每个奇数元素
    vector<int> vi = {0,1,2,3,4,5,6,7,8,9};
    auto iter = vi.begin();
    while (iter != vi.end()) {
        if (*iter % 2) {
            iter = vi.insert(iter, *iter);  // 复制当前元素
            iter = vi.insert(iter, *iter++);
            iter += 2;  // 向前移动迭代器，跳过当前元素以及插入到它之前的元素
        } else {
            iter = vi.erase(iter);  // 删除偶数元素
            // 不应向前移动迭代器，iter指向我们删除的元素之后的元素
        }
    }

    // string 的额外操作
    const char *cp = "Hello World!!!";
    char noNull[] = {'H', 'i'};
    string s1(cp);  // s1初始化成 Hello World!
    string s2(noNull, 2);  // 从 noNull 中拷贝 2个字符, s2 = "Hi"
    string s3(noNull);  // 为定义,nuNull 不是以空字符结尾
    string s4(cp + 6, 5);  // 从 cp[6]开始拷贝5个字符， s4 = "World"
    string s5(s1, 6, 5);  // 从 s1[6] 开始拷贝5个字符，s5 = "World"
    string s6(s1, 6);  // 从 s1[6]开始拷贝生于字符, s6 = "World!!!"
    string s7(s1, 6, 20);  // 正确，拷贝以空字符结束, s7 = "Wold!!!"
    string s8(s1, 16); // 错误，超出范围

    // string 的 find操作
    string name("AnnaBelle");
    auto pos1 = name.find("Anna");  // pos1 = 0
    string lowercase("annabelle");
    auto pos2 = lowercase.find("Anna");  // pos2 = string::npos
    string numbers("0123456789"), name1("r2d2");
    auto pos3 = name1.find_first_of(numbers);  // pos3 = 1
    string dept("03714p3");
    auto pos4 = dept.find_first_not_of(numbers);  // pos4 = 5
    string::size_type pos5 = 0;
    // 每步循环查找 name中下一个数
    while ((pos5 = name.find_first_of(numbers, pos5)) != string::npos) {
        cout << "found number at index: " << pos5 << " element is "
             << name[pos5] << endl;
        ++pos5;  // 移动到下一个字符
    }
    string river("Mississippi");
    auto first_pos = river.find("is");  // 返回 1
    auto last_pos = river.rfind("is");  // 返回 4

    // 数值转换
    string s_v = "pi = 3.14";
    double d = stod(s_v.substr(s2.find_first_of("+-.0123456789")));

    // 适配器
//    stack<int> stk(deq);
    vector<string> svec;
    stack<string, vector<string>> str_stk;  // 在 vector 上实现的空栈
    // 在 vector上实现的空栈，初始化使用 svec的拷贝
    stack<string, vector<string>> str_stk2(svec);

    stack<int> intStack;  // 空栈
    for (size_t ix = 0; ix != 10; ix++) {
        intStack.push(ix);  // 填满栈
    }
    while (!intStack.empty()) {
        int value = intStack.top();  // 获取栈顶元素
        intStack.pop();  // 弹出栈顶元素，继续循环
    }

    return 0;
}
